/***************************************************************************
 *   Copyright (C) 2008 by Burdakov Daniel   *
 *   kreved@kreved.org   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "nclient.h"
#include <time.h>
#include <QCryptographicHash>

QString sha1hex(QString s)
{
    return QCryptographicHash::hash(s.toLatin1(), QCryptographicHash::Sha1).toHex();
}

QString md5hex(QString s)
{
    return QCryptographicHash::hash(s.toLatin1(), QCryptographicHash::Md5).toHex();
}

nclient::nclient()
{
    shuttingDown = false;
    authFailed = false;
    config = new QSettings("kreved.org", "nclient");
    skey = config->value("skey", "").toString();
    prefix = config->value("prefix", "/").toString();
    createActions();
    createTrayIcon();
    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), 
        this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
    setIcon(":/images/offline.png");
    setToolTip(tr("Trying to connect"));
    
    usernameLabel = new QLabel(tr("&Username:"));
    usernameEdit = new QLineEdit("");
    usernameLabel->setBuddy(usernameEdit);
    passwordLabel = new QLabel(tr("&Password:"));
    passwordEdit = new QLineEdit("");
    passwordEdit->setEchoMode(QLineEdit::Password);
    passwordLabel->setBuddy(passwordEdit);
    rememberCheckBox = new QCheckBox(tr("&Remember authentication data"));
    btnOK = new QPushButton(tr("OK"));
    btnOK->setDefault(true);
    btnCancel = new QPushButton(tr("Cancel"));
    connect(btnCancel, SIGNAL(clicked()), this, SLOT(close()));
    connect(btnOK, SIGNAL(clicked()), this, SLOT(saveSettings()));
    
    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(usernameLabel, 0, 0);
    mainLayout->addWidget(usernameEdit, 0, 1, 1, 2);
    mainLayout->addWidget(passwordLabel, 1, 0);
    mainLayout->addWidget(passwordEdit, 1, 1, 1, 2);
    mainLayout->addWidget(rememberCheckBox, 2, 0, 1, 3);
    QHBoxLayout *v = new QHBoxLayout;
    v->addWidget(btnOK);
    v->addWidget(btnCancel);
    mainLayout->addLayout(v, 3, 1, 1, 2);
    
    setLayout(mainLayout);
    
    setWindowTitle(tr("NClient settings"));
    
    http = new QHttp();
    host = config->value("host", "192.168.0.157").toString();
    connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
        this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
    connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool)));
    trayIcon->show();
    
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(600000); // 10 minutes
    
    update();
}

void nclient::createActions()
{
    
    showStatusAction = new QAction(tr("S&how status"), this);
    connect(showStatusAction, SIGNAL(triggered()), this, SLOT(showStatus()));
    
    updateAction = new QAction(tr("&Update"), this);
    connect(updateAction, SIGNAL(triggered()), this, SLOT(update()));
    
    settingsAction = new QAction(tr("&Settings"), this);
    connect(settingsAction, SIGNAL(triggered()), this, SLOT(openSettings()));
    
    quitAction = new QAction(tr("&Quit"), this);
    connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));
}

void nclient::createTrayIcon()
{
    trayIconMenu = new QMenu(this);
    trayIconMenu->addAction(showStatusAction);
    trayIconMenu->addAction(updateAction);
    trayIconMenu->addAction(settingsAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);

    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayIconMenu);
}

void nclient::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
	case QSystemTrayIcon::Trigger:
	case QSystemTrayIcon::DoubleClick:
	    update();
	    break;
	case QSystemTrayIcon::MiddleClick:
	    showStatus();
	    break;
	default:
	    ;
    }
}

void nclient::setIcon(QString ico)
{
    QIcon icon = QIcon(ico);
    trayIcon->setIcon(icon);
    setWindowIcon(icon);
}

void nclient::setToolTip(QString text)
{
    trayIcon->setToolTip(text);
}

void nclient::showStatus()
{
    QMessageBox::information(0, tr("Status"), trayIcon->toolTip());
}

void nclient::openSettings()
{
    passwordEdit->setText("");
    usernameEdit->setText(config->value("username", "").toString());
    rememberCheckBox->setChecked(config->value("remember", true).toBool());
    show();
}

void nclient::saveSettings()
{
    skey = calc_key();
    bool remember = rememberCheckBox->isChecked();
    config->setValue("username", usernameEdit->text());
    config->setValue("remember", remember);
    passwordEdit->setText("");
    if(remember)
	config->setValue("skey", skey);
    else 
	config->setValue("skey", "");
    close();
    update();
}

QString nclient::calc_key()
{
    return sha1hex(usernameEdit->text()+md5hex(passwordEdit->text()));
}

void nclient::update()
{
    reqID = -1;
    http->abort();
    http->setHost(host);
    reqID = http->get(prefix+"/scripts/api?skey="+skey+"&inet=900");
}

void nclient::disableInet()
{
    reqID = -1;
    http->abort();
    http->setHost(host);
    reqID = http->get(prefix+"/scripts/api?skey="+skey+"&inet=-1");
}

void nclient::readResponseHeader(const QHttpResponseHeader &responseHeader)
{
    authFailed = false;
    if(responseHeader.statusCode()==403)
    {
	authFailed = true;
        http->abort();
    }
}

void nclient::httpRequestFinished(int id, bool error)
{
    if(id != reqID)
	return;
    if(shuttingDown)
    { 
        qApp->quit();
        return;
    }
    if(error)
        if(authFailed)
           {
	       err(tr("Authentication failed."));
	       setIcon(":/images/offline.png");
	   }
        else
	   {
	       err(http->errorString());
	       setIcon(":/images/offline.png");
	   }
    else
	parseResponse(http->readAll().data());
}

void nclient::parseResponse(QString s)
{
    // format: login, email, balance, ip, status, last_activity, tarif_id, last_abonent_payment, credit, prepaid_traffic
    //trayIcon->showMessage("NClient", s, QSystemTrayIcon::Information);
    char login[100], email[100], ip[100], balance[100], credit[100];
    long long status, last_activity, tarif_id, last_abonent_payment, prepaid_traffic;
    sscanf(s.toLatin1().data(), "%s %s %s %s %lld %lld %lld %lld %s %lld", login, email, balance, ip, &status,
        &last_activity, &tarif_id, &last_abonent_payment, credit, &prepaid_traffic);
    //trayIcon->showMessage("NClient", ip, QSystemTrayIcon::Information);
    prepaid_traffic /= 1048576;
    QString sstatus;
    if(status>0)
        {
            sstatus="Enabled";
            setIcon(":/images/on.png");
        }
    else
        {
            sstatus="Disabled";
            setIcon(":/images/off.png");
        }
    char tt[10000];
    
    char tmstr[200];
    time_t t;
    struct tm *tmp;
    t = time(NULL);
    tmp = localtime(&t);
    strftime(tmstr, sizeof(tmstr), "%H:%M:%S", tmp);
    
    sprintf(tt, "%s %s (%s)\nInternet: %s\nBalance: %s UAH, credit: %s UAH\nPrepaid traffic: %lld Mb",
        tmstr, login, ip, sstatus.toLatin1().data(), balance, credit, prepaid_traffic);
    setToolTip(tt);
}

void nclient::err(QString s)
{
    setToolTip(s);
    trayIcon->showMessage("NClient", s, QSystemTrayIcon::Critical);
}

void nclient::quit()
{
    shuttingDown = true;
    disableInet();
    QTimer::singleShot(5000, qApp, SLOT(quit()));
}

nclient::~nclient()
{
    config->sync();
}
